using OhioState.Math;

namespace OhioState.Physics
{
    /// <summary>
    /// RigidBodyUpdateCommand Class that updates the states of a rigid body
    /// </summary>
    public class RigidBodyUpdateCommand : DynamicModelUpdateCommand
    {
        private IDynamicModel _model;
        private double _timeStamp;
        private bool _dataChanged = false;
        private Vector3 _newPosition;
        private Vector3 _newVelocity;

        public RigidBodyUpdateCommand(IDynamicModel model)
        {
            _model = model;
        }
        /// <summary>
        /// The Execute method should be called only once per update-render
        /// cycle. The thread locking assumes that there is only one updater
        /// per model, hence reading is safe. If we also assume this is run
        /// on the rendering thread, then there is no need to lock the model
        /// during updates as well.
        /// </summary>
        /// <param name="time">The current time of the simulation in seconds</param>
        /// <param name="elapsedSeconds">The time duration since the last update cycle.</param>
        public override void Execute(double time, double elapsedSeconds)
        {
            Vector3 position = _model.Position;
            Vector3 velocity = _model.Velocity;
            double elapsedTime = elapsedSeconds;
            lock (this)
            {
                if (_dataChanged)
                {
                    elapsedTime = time - _timeStamp;
                    position = _newPosition;
                    velocity = _newVelocity;
                    _dataChanged = false;
                }
            }
            position = position + (float)elapsedSeconds * velocity;
            if (position.x < -10.0f) position.x = -10.0f;
            if (position.x > 10.0f) position.x = 10.0f;
            if (position.y < -10.0f) position.y = -10.0f;
            if (position.y > 10.0f) position.y = 10.0f;
            position.z = 0.0f;
            //if (position.z < -10.0f) position.z += 20.0f;
            //if (position.z > 10.0f) position.z -= 20.0f;
            _model.SetPosition(position);
            _model.SetVelocity(velocity);
        }
        public override void MoveModel(double time, Vector3 position, Vector3 velocity)
        {
            lock (this)
            {
                _timeStamp = time;
                _newPosition = position;
                _newVelocity = velocity;
                _dataChanged = true;
            }
        }
    }
}
